-
Notifications
You must be signed in to change notification settings - Fork 94
LangGraph Samples #272
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
LangGraph Samples #272
Conversation
- Add langgraph_samples/basic/hello_world/ demonstrating basic Temporal + LangGraph integration with a single-node graph - Add langgraph dependency group to pyproject.toml - Update langchain dependency group to 0.3.x for compatibility with langgraph (requires langchain-core>=0.2.27)
Document the ReAct agent sample showing durable tool execution with temporal_tool() and the think-act-observe pattern.
Update all run_worker.py and run_workflow.py files to use the ClientConfig.load_client_connect_config() pattern for environment-based configuration support. Also simplify react_agent run_workflow.py to run a single query with clean output. Add CLAUDE.md documenting the client initialization pattern.
Add remaining sample files: - react_agent: graph, tools, workflow definitions - approval_workflow: graph, workflow with human-in-the-loop pattern
…ADME - Add comprehensive README for human_in_loop/approval_workflow sample - Update react_agent README to reflect simplified single-query output
…l_workflow - Add notify_approver activity that prints approval instructions with workflow ID - Add run_respond.py CLI tool for approvers to approve/reject workflows - Update workflow to call notification activity when hitting interrupt - Simplify run_workflow.py to start one workflow and wait for result - Update README with 3-terminal workflow instructions
…act_agent The react_agent sample was using ChatOpenAI directly without wrapping it with temporal_model(), meaning LLM calls were not durable. Now both LLM calls and tool invocations run as Temporal activities.
Use the new Temporal-provided create_durable_react_agent which: - Automatically wraps model and tools for durable execution - Runs agent nodes inline in workflow with model/tool calls as activities
Use the new model_activity_options and tool_activity_options parameters with activity_options() instead of the old individual timeout parameters.
Update react_agent sample to use LangGraph's native create_react_agent instead of the removed create_durable_react_agent wrapper. The Temporal integration now works directly with native LangGraph APIs - each node runs as a Temporal activity, providing durability without special wrappers.
…c loop - Change query to require multiple tool calls (weather + temperature conversion) - Remove unused search_knowledge tool, keep only get_weather and calculate - Update README to document multi-step reasoning behavior
- Add agentic_rag sample with document grading and query rewriting - Add README files for human_in_loop and RAG sample categories - Update main README to link to all sample categories - Add langchain and langchain-openai dependencies for RAG sample
Update installation instructions to reflect that the LangGraph integration is currently available as a preview feature in branch repositories: - SDK: mfateev/sdk-python@langgraph-plugin - Samples: mfateev/samples-python@langgraph_plugin
create_agent always returns a compiled graph, so no need for defensive compile() call with hasattr check.
…t_agent - Update imports from langgraph.prebuilt to langchain.agents - Change prompt parameter to system_prompt - Add multi_agent/supervisor sample - Document the correct API in CLAUDE.md
- Deep Research Agent: Multi-step research with parallel search execution using Send API, result evaluation, and report synthesis - Plan-and-Execute Agent: Structured planning with sequential step execution, dynamic replanning, and tool integration - Reflection Agent: Generate-critique-revise loop with quality scoring and iterative improvement until criteria met
- Update all README files to use `uv run` format for running scripts - Remove redundant Usage sections from run_*.py files - Keep usage documentation centralized in README files only
- Replace mock search results with real DuckDuckGo web search - Add langchain-community and duckduckgo-search dependencies - Update README to reflect real search functionality - Add error handling for failed searches
Move all samples from nested category directories to top level: - basic/hello_world -> hello_world - basic/react_agent -> react_agent - human_in_loop/approval_workflow -> approval_workflow - multi_agent/supervisor -> supervisor - rag/agentic_rag -> agentic_rag - rag/deep_research -> deep_research - planning/plan_and_execute -> plan_and_execute - advanced/reflection -> reflection Update all import paths accordingly and refresh README.md with a table listing all samples.
- Fix import sorting (I001) across all sample modules - Apply ruff formatting to 11 files - Add type annotations for mypy (executor_agent, critique, plan) - Use cast() for structured output return types
- Test basic workflow execution with query processing - Test empty query handling - Add fixture to clear global registry between tests
Tests: - Added tests for all LangGraph samples (hello_world, approval_workflow, react_agent, supervisor, agentic_rag, deep_research, plan_and_execute, reflection) - Added conftest.py with shared fixtures (clear_registry, requires_openai) - Tests requiring OpenAI API are skipped when OPENAI_API_KEY is not set Bug fixes: - Fixed serialization bugs in reflection and plan_and_execute samples - After Temporal serialization, Pydantic models become dicts - Added helper functions to handle both object and dict access for: - Critique objects in reflection sample - Plan, PlanStep, StepResult objects in plan_and_execute sample
Shows how to call Temporal activities directly from a LangGraph node using the run_in_workflow=True metadata option.
…oaches - approval_workflow_interrupt: Uses LangGraph interrupt() with workflow signal handling - approval_workflow_signal: Uses run_in_workflow=True to handle signals in graph node
- Renamed approval_workflow_signal to approval_workflow_condition - Both samples now in langgraph_samples/human_in_the_loop/ - Updated all import paths and documentation
- approval_workflow_interrupt → approval_graph_interrupt - approval_workflow_condition → approval_wait_condition
- Fix approval_wait_condition graph to use temporal_node_metadata() - Import workflow inside function for sandboxing - Add tests for approval_graph_interrupt sample - Add tests for approval_wait_condition sample - Remove old approval_workflow_test.py
Rename the samples directory and test directory to match the plugin name for better clarity and consistency.
Add get_graph_ascii() and get_graph_mermaid() queries to both human_in_the_loop workflow samples, demonstrating how to expose graph execution progress via Temporal queries. These queries return: - ASCII art diagram with progress indicators (✓/▶/○) - Mermaid flowchart with colored nodes by status
- Add GraphStateResponse dataclass with typed ApprovalState values - Cast snapshot.values to ApprovalState for type safety - Flatten the response structure for easier consumption: - values: typed ApprovalState - next: list of next nodes - step: current step count - interrupted: boolean flag - interrupt_node: node that triggered interrupt - interrupt_value: value passed to interrupt()
drewhoskins-temporal
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor stuff I noticed as I went through and tried to understand. Feel free to ignore if too early.
| """ | ||
| self._app = lg_compile("approval_workflow") | ||
|
|
||
| # Handle both dataclass and dict input (Temporal deserializes to dict) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks offputting, and I don't understand why you can't just assume it's a dataclass given that the ApprovalRequest input is typed as a dataclass.
| def __init__(self) -> None: | ||
| self._approval_response: dict[str, Any] | None = None | ||
| self._interrupt_value: dict[str, Any] | None = None | ||
| self._app: Any = None # Store runner for visualization queries |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Confused here.
- Isn't this a langgraph construct?
- specify a real type hint?
- What is a "store runner" ?
| Returns: | ||
| The final state containing result and executed status. | ||
| """ | ||
| self._app = lg_compile("approval_workflow") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Initialize this in @workflow.init?
| Can be rendered in GitHub, Notion, or any Mermaid-compatible viewer. | ||
| """ | ||
| if self._app is None: | ||
| return "Graph not yet initialized" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: This should never happen, right? Why not fail hard?
| | Sample | Description | | ||
| |--------|-------------| | ||
| | [hello_world](./hello_world/) | Simple starter example demonstrating basic plugin setup and graph registration | | ||
| | [activity_from_node](./activity_from_node/) | Calling Temporal activities from a graph node using run_in_workflow | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not clear what run_in_workflow means, especially at this top level. Is it an implementation detail? I'm wondering what I will get out of looking at this sample.
| @@ -0,0 +1,51 @@ | |||
| # Activity from Node | |||
|
|
|||
| Demonstrates calling Temporal activities directly from a LangGraph node using the `run_in_workflow` feature. | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same comment as above. Say what the upshot is here and then introduce the flag lower down.
At this point, I'm assuming the whole point of a langgraph integration is that I can run it in a temporal workflow.
Summary
Add LangGraph samples demonstrating the Temporal LangGraph integration for durable AI agent workflows.
Samples Included
Key Features Demonstrated
Prerequisites
Running
Related PR